home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / networke / cow / cowl-1.000 / cowl-1 / option.c < prev    next >
C/C++ Source or Header  |  1994-04-16  |  32KB  |  1,373 lines

  1. /*
  2.  * option.c
  3.  */
  4. #include "copyright.h"
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include "Wlib.h"
  11. #include "defs.h"
  12. #include "struct.h"
  13. #include "data.h"
  14. #include "packets.h"
  15.  
  16. int             notdone;    /* not done flag */
  17. int             old_showgalactic;
  18. int             old_draw_map_names;
  19. int             old_show_owner_map;
  20. int             dummy = 1;
  21. int             write_configuration = 1;
  22.  
  23. #ifdef LOGMESG
  24. extern char    *logFileName;    /* from main.c */
  25. extern char    *defaultsFile;    /* from main.c */
  26. #endif
  27.  
  28. #ifdef ROTATERACE
  29. static int      old_rotate, old_rotate_deg;
  30. #endif
  31.  
  32. #ifndef DEFAULT_UPDATE_SPEED
  33. #define DEFAULT_UPDATE_SPEED 4
  34. #endif
  35.  
  36. int             updateSpeed = DEFAULT_UPDATE_SPEED;
  37. static int      lastUpdateSpeed = DEFAULT_UPDATE_SPEED;
  38.  
  39. static char     newkeys[17];
  40. static char     newckeys[17];
  41. static char     newbuttons[17];
  42. char            cname[17] = "";
  43. static char     oplist[80];
  44. static char     nplist[80];
  45. static char     macro_key[4];
  46. static char     logfile[65];
  47. static char     xtrekrcfile[65];
  48. static char     singlemacros[33];
  49.  
  50. #if (defined( DEBUG) || defined (BITMAP_DEBUG)) && defined(DYNAMIC_BITMAPS)
  51. extern int      OwnBitmapNum;
  52. #endif
  53.  
  54. char           *localmes[] =
  55. {"Show owner on local planets",
  56.   "Show resources on local planets",
  57.   "Show nothing on local planets",
  58. ""};
  59.  
  60. char           *galacticmes[] =
  61. {"Show owner on galactic map",
  62.   "Show resources on galactic map",
  63.   "Show nothing on galactic map",
  64. ""};
  65.  
  66. char           *phasermes[] = 
  67. {"Don't show phaser messages",
  68.  "Show phaser messages on all window",
  69.  "Show phaser messages on team window",
  70.  "Show phaser messages on indiv window",
  71.  "Show phaser messages on kill window",
  72.  "Show phaser messages on total window",
  73.  ""
  74. };
  75.  
  76. #ifdef ROTATERACE
  77. char           *rotatemess[] =
  78. {"Don't rotate galaxy",
  79.   "Rotate galaxy 90 degrees",
  80.   "Rotate galaxy 180 degrees",
  81.   "Rotate galaxy 270 degrees",
  82.   ""
  83. };
  84.  
  85. #endif
  86.  
  87. char           *mapupdates[] =
  88. {"Don't update galactic map",
  89.   "Update galactic map rarely",
  90.   "Update galactic map frequently",
  91. ""};
  92.  
  93. static char    *lockoptions[] =
  94. {"Don't show lock icon",
  95.   "Show lock icon on galactic map only",
  96.   "Show lock icon on tactical map only",
  97. "Show lock icon on both map windows", ""};
  98.  
  99. /* useful for options that are an int with a range */
  100. struct int_range
  101. {
  102.   int             min_value;    /* value is >= this */
  103.   int             max_value;    /* value is <= this */
  104.   int             increment;    /* a click raises/lowers this amount */
  105. };
  106.  
  107.  
  108. /*
  109.  * Only one of op_option, op_targetwin, and op_string should be defined. If
  110.  * op_string is defined, op_size should be too and op_text is used without a
  111.  * "Don't" prefix. if op_range is defined, there should be a %d in op_text
  112.  * for it, op_size will be non-useful, and the 'Don't ' prefix won't appear
  113.  */
  114. struct option
  115. {
  116.   int             op_num;
  117.   char           *op_text;    /* text to display when on */
  118.   int            *op_option;    /* variable to test/modify (optional) */
  119.   W_Window       *op_targetwin;    /* target window to map/unmap (optional) */
  120.   char           *op_string;    /* string to modify (optional) */
  121.   int             op_size;    /* size of *op_string (optional) */
  122.   char          **op_array;    /* array of strings to switch between */
  123.   struct int_range *op_range;    /* struct definint an integer range option */
  124. };
  125.  
  126. /* for the paged options menus */
  127. struct option_menu
  128. {
  129.   int             page_num;    /* page number of this menu */
  130.   struct option_menu *Next;
  131.   struct option  *menu;        /* pointers to arrary of options */
  132.   int             numopt;    /* number of options in this menu page */
  133.   int             updated;    /* 1 if options can be changed externally */
  134. };
  135.  
  136. /* pointer to first entry in the options menu list */
  137. struct option_menu *FirstMenu = NULL;
  138. struct option_menu *CurrentMenu = NULL;    /* menu currently looked at */
  139. int             MenuPage = 0;    /* current menu page */
  140. int             MaxOptions = 0;    /* maximum number of options in all menu
  141.                  * pages */
  142. struct int_range MenuPages =
  143. {0, 1, 1};
  144.  
  145.  
  146. /* updates: use of the int range thing... */
  147. struct int_range updates_range =
  148. {1, 10, 1};
  149.  
  150. /* range of menus. Will be updated when menu list is assembled */
  151. struct int_range Menus_Range =
  152. {0, 1, 1};
  153.  
  154. #if (defined( DEBUG) || defined (BITMAP_DEBUG)) && defined(DYNAMIC_BITMAPS)
  155. struct int_range bitmap_range =
  156. {0, 50, 1};
  157.  
  158. #endif
  159.  
  160. struct int_range dummy_range =
  161. {1, 1, 0};
  162.  
  163. struct int_range write_configuration_range =
  164. {1, 1, 0};
  165.  
  166. char           *clockmes[] =
  167. {"No clock",
  168.   "Clock format hours:minutes",
  169.   "Clock format hours:minutes:seconds",
  170.   ""};
  171.  
  172. struct int_range keep_info_range =
  173. {0, 60, 1};
  174.  
  175. struct int_range phaser_range =
  176. {0, 60, 1};
  177.  
  178. struct int_range motion_thresh_range =
  179. {0, 64, 1};
  180.  
  181. struct int_range motion_mouse_range =
  182. {0, 1, 1};
  183. static char    *motion_mouse_options[] =
  184. {"Don't use continuous mouse mode",
  185.   "Use continuous mouse mode",
  186. ""};
  187.  
  188. struct int_range multiline_macro_range =
  189. {0, 1, 0};
  190. static char    *multiline_macro_options[] =
  191. {"Don't ignore multi-line macros",
  192.   "Ignore multi-line macros",
  193. ""};
  194.  
  195. struct int_range beeplite_planet_range =
  196. {0, 50, 1};
  197. struct int_range beeplite_player_range =
  198. {0, 50, 1};
  199.  
  200. struct int_range beeplite_range =
  201. {0, 1, 1};
  202. static char    *beeplite_options[] =
  203. {"Don't use RCD highlighting",
  204.   "Use RCD highlighting",
  205. ""};
  206.  
  207. static char    *moo_bitmap_options[] =
  208. {"Don't use moo bitmaps",
  209.   "Use rabbit ear bitmaps",
  210.   "Use ZZ minimal bitmaps",
  211. ""};
  212.  
  213.  
  214. /* menus */
  215. struct option   Window_Menu[] =
  216. {
  217.   {0, "Window Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
  218.   {1, "Page %d (click to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
  219.   {2, "show \"all\" message window", 0, &messwa, 0, 0, NULL, NULL},
  220.   {4, "show \"team\" message window", 0, &messwt, 0, 0, NULL, NULL},
  221.   {5, "show \"your\" message window", 0, &messwi, 0, 0, NULL, NULL},
  222.   {6, "show \"kill\" message window", 0, &messwk, 0, 0, NULL, NULL},
  223.   {7, "show \"total\" message window", 0, &reviewWin, 0, 0, NULL, NULL},
  224.   {7, "show phaser log window", &phaserWindow, &phaserwin, 0, 0, NULL},
  225.   {8, "show statistic window", 0, &statwin, 0, 0, NULL, NULL},
  226.   {11,  "", &phas_msg, 0, 0, 0, phasermes, NULL},
  227.  
  228. #ifdef NETSTAT
  229.   {8, "show LagMeter ", &netstat, 0, 0, 0, NULL, NULL},
  230. #endif
  231.  
  232. #ifdef PING
  233.   {8, "show ping stats window", 0, &pStats, 0, 0, NULL},
  234. #endif
  235.   {9, "show UDP control window", 0, &udpWin, 0, 0, NULL, NULL},
  236.   {9, "show help window", 0, &helpWin, 0, 0, NULL, NULL},
  237.  
  238. #ifdef XTREKRC_HELP
  239.   {9, "show xtrekrc defaults window", 0, &defWin, 0, 0, NULL, NULL},
  240. #endif
  241. #ifdef MAKE_XTREKRC
  242.   {17, "write configuration", &write_configuration, 0, 0, 0, NULL,
  243.   &write_configuration_range},
  244. #endif
  245.   {10, "done", ¬done, 0, 0, 0, NULL, NULL},
  246.   {-1, NULL, 0, 0, 0, 0, NULL, NULL}
  247. };
  248.  
  249. struct option   Features_Menu[] =
  250. {
  251.   {0, "Features Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
  252.   {1, "Page %d (click to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
  253.   {2, "show tactical planet names", &namemode, 0, 0, 0, NULL, NULL},
  254.   {3, "show shields", &showShields, 0, 0, 0, NULL, NULL},
  255.   {4, "", &mapmode, 0, 0, 0, mapupdates, NULL},
  256.   {5, "stay peaceful when reborn", &keeppeace, 0, 0, 0, NULL, NULL},
  257.   {6, "new keymap entries: %s", 0, 0, newkeys, 13, NULL, NULL},
  258.   {7, "", &showlocal, 0, 0, 0, localmes, NULL},
  259.   {8, "", &showgalactic, 0, 0, 0, galacticmes, NULL},
  260.   {9, "%d updates per second", &updateSpeed, 0, 0, 0, 0, &updates_range},
  261.   {10, "report kill messages", &reportKills, 0, 0, 0, NULL, NULL},
  262.   {12, "show tractor/pressor", &showTractorPressor, 0, 0, 0, NULL, NULL},
  263.  
  264. #ifdef SHORT_PACKETS
  265.   {13, "receive short packets", &recv_short_opt, 0, 0, 0, NULL, NULL},
  266.   {14, "receive threshold: %s", 0, 0, recv_threshold_s, 13, NULL, NULL},
  267. #endif
  268.  
  269. #ifdef NEW_PL
  270.   {15, "show new playerlist", &newPlist, 0, 0, 0, NULL, NULL},
  271. #endif
  272.   {16, "use new message flags", &new_messages, 0, 0, 0, NULL, NULL},
  273.  
  274. #ifdef DASHBOARD
  275.   {17, "use dashboard", &dashboard, 0, 0, 0, NULL, NULL},
  276. #endif
  277.  
  278. #ifdef NEW_DASHBOARD_2
  279.   {17, "use new dashboard", &cup_half_full, 0, 0, 0, NULL, NULL},
  280. #endif
  281.  
  282. #ifdef MAKE_XTREKRC
  283.   {17, "write configuration", &write_configuration, 0, 0, 0, NULL,
  284.   &write_configuration_range},
  285. #endif
  286.   {17, "done", ¬done, 0, 0, 0, NULL, NULL},
  287.   {-1, NULL, 0, 0, 0, 0, NULL, NULL}
  288. };
  289.  
  290.  
  291. struct option   SillyFeatures_Menu[] =
  292. {
  293.   {0, "Extra Features Menu (0)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
  294.   {1, "Page %d (click to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
  295.   {13, "", &showLock, 0, 0, 0, lockoptions, NULL},
  296.   {11, "sort players in player window", &sortPlayers, 0, 0, 0, NULL, NULL},
  297.   {12, "show tractor/pressor beams", &showTractorPressor, 0, 0, 0, NULL, NULL},
  298.   {12, "show tractors after lock ", &continueTractor, 0, 0, 0, NULL, NULL},
  299.  
  300. #ifdef MOOBITMAPS
  301.  
  302. #ifdef ZZ_BITMAPS
  303.   {12, "", &myPlanetBitmap, 0, 0, 0, moo_bitmap_options, NULL},
  304. #else
  305.   {12, "Use 'Moo' planet bitmaps", &myPlanetBitmap, 0, 0, 0, NULL, NULL},
  306. #endif
  307.  
  308. #endif
  309.   {12, "alert on extra border(s)", &extraBorder, 0, 0, 0, NULL, NULL},
  310.  
  311. #ifdef LOGMESG
  312.   {12, "log messages", &logMess, 0, 0, 0, NULL, NULL},
  313. #endif
  314.  
  315. #ifdef ROTATERACE
  316.   {14, "", &rotate, 0, 0, 0, rotatemess, NULL},
  317. #endif
  318.   {12, "use message warp", &warp, 0, 0, 0, NULL, NULL},
  319.  
  320. #if (defined( DEBUG) || defined (BITMAP_DEBUG)) && defined(DYNAMIC_BITMAPS)
  321.   {10, "Own bitmap number: %d", &OwnBitmapNum, 0, 0, 0, NULL, &bitmap_range},
  322. #endif
  323.  
  324. #ifdef VSHIELD_BITMAPS
  325.   {12, "show shield damage", &VShieldBitmaps, 0, 0, 0, NULL, NULL},
  326. #endif
  327.   {12, "show last msg in msg win", &use_msgw, 0, 0, 0, NULL, NULL},
  328.  
  329. #ifdef ROMVLVS_BITMAPS
  330.   {10, "use ROMVLVS bitmap", &ROMVLVS, 0, 0, 0, NULL, NULL},
  331. #endif
  332.  
  333. #ifdef SHOW_MY_SPEED
  334.   {2, "show speed on tactical", &showMySpeed, 0, 0, 0, NULL, NULL},
  335. #endif
  336.  
  337. /* SRS 3/15/94 -- When you enter game, send request for full update */
  338.  
  339.   {13, "request update on enter", &askforUpdate, 0,0,0, NULL, NULL},
  340.  
  341. #ifdef MAKE_XTREKRC
  342.   {17, "write configuration", &write_configuration, 0, 0, 0, NULL,
  343.   &write_configuration_range},
  344. #endif
  345.   {17, "done", ¬done, 0, 0, 0, NULL, NULL},
  346.   {-1, NULL, 0, 0, 0, 0, NULL, NULL}
  347. };
  348.  
  349. struct option   SillyFeatures_Menu1[] =
  350. {
  351.   {0, "Extra Features Menu (1)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
  352.   {1, "Page %d (click to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
  353.   {3, "show stats", &showStats, 0, 0, 0, NULL, NULL},
  354.   {3, "fill lock-on triangle", &fillTriangle, 0, 0, 0, NULL, NULL},
  355.   {3, "clock mode: %d", &tclock, 0, 0, 0, clockmes, NULL},
  356.   {3, "align kill messages", &abbr_kmesg, 0, 0, 0, NULL, NULL},
  357.  
  358. #ifdef TNG_FED_BITMAPS
  359.   {3, "use TNG style bitmaps", &use_tng_fed_bitmaps, 0, 0, 0, NULL, NULL},
  360. #endif
  361.  
  362. #ifdef VARY_HULL
  363.   {3, "warn hull", &vary_hull, 0, 0, 0, NULL, NULL},
  364. #endif
  365.  
  366. #ifdef KEEP_INFO
  367.   {3, "updates to keep info windows: %d", &keepInfo, 0, 0, 0, NULL, &keep_info_range},
  368. #endif
  369.   {3, "show player status", &plshowstatus, 0, 0, 0, NULL, NULL},
  370.  
  371. #ifdef SHOW_IND
  372.   {3, "show independant planets with X", &showIND, 0, 0, 0, NULL, NULL},
  373. #endif
  374. #ifdef MAP_NAMES
  375.   {2, "show map planet names", &draw_map_names, 0, 0, 0, NULL, NULL},
  376.   {2, "show owner on map", &show_owner_map, 0, 0, 0, NULL, NULL},
  377. #endif
  378.   {3, "enemy phaser width: %d", &enemyPhasers, 0, 0, 0, NULL, &phaser_range},
  379.  
  380. #ifdef MOTION_MOUSE
  381.   {3, "", &motion_mouse, 0, 0, 0, motion_mouse_options, &motion_mouse_range},
  382.   {3, "Motion threshold for continuous mouse: %d", &user_motion_thresh, 0, 0, 0, NULL, &motion_thresh_range},
  383. #endif
  384.  
  385. #ifdef SHIFTED_MOUSE
  386.   {3, "use shifted mouse for more buttons", &extended_mouse, 0, 0, 0, NULL, NULL},
  387. #endif
  388.   {3, "show motd when on wait queue", &showMotdOnQ, 0, 0, 0, NULL, NULL},
  389.  
  390. #ifdef SHOW_FUEL_ON_LOCAL
  391.   {3, "show fuel level on local", &show_fuel_on_local, 0, 0, 0, NULL, NULL},
  392. #endif
  393.  
  394. #ifdef MAKE_XTREKRC
  395.   {17, "write configuration", &write_configuration, 0, 0, 0, NULL,
  396.   &write_configuration_range},
  397. #endif
  398.   {17, "done", ¬done, 0, 0, 0, NULL, NULL},
  399.   {-1, NULL, 0, 0, 0, 0, NULL, NULL}
  400. };
  401.  
  402. struct option   SillyFeatures_Menu2[] =
  403. {
  404.   {0, "Extra Features Menu (2)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
  405.   {1, "Page %d (click to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
  406.  
  407. #ifdef MAP_NAMES
  408.   {2, "show owner on tactical", &show_owner_tact, 0, 0, 0, NULL, NULL},
  409. #endif
  410.   
  411. #ifdef JUBILEE_PHASERS
  412.   {6, "use colorful phasers", &jubilee_phasers, 0, 0, 0, NULL, NULL},
  413. #endif
  414.  
  415. #ifdef MAKE_XTREKRC
  416.   {6, "name: %s", 0, 0, cname, 16, NULL, NULL},
  417.   {3, " ", &dummy, 0, 0, 0, NULL, &dummy_range},
  418. #endif
  419.   {6, "new buttonmap entries: %s", 0, 0, newbuttons, 16, NULL, NULL},
  420.  
  421. #ifdef CONTROL_KEY
  422.   {6, "new ckeymap entries: %s", 0, 0, newckeys, 16, NULL, NULL},
  423. #endif
  424.  
  425. #ifdef CLOAK_CHARS
  426.   {6, "map cloak chars: %s", 0, 0, cloakChars, 3, NULL, NULL},
  427. #endif
  428.  
  429. #ifdef PLIST
  430.   {6, "playerlist: %s", 0, 0, oplist, 16, NULL, NULL},
  431. #endif
  432.  
  433. #ifdef FEATURE
  434.   {6, "macrokey: %s", 0, 0, macro_key, 4, NULL, NULL},
  435.   {6, "single macros: %s", 0, 0, singlemacros, 33, NULL, NULL},
  436. #endif
  437.   {3, " ", &dummy, 0, 0, 0, NULL, &dummy_range},
  438.  
  439. #ifdef LOGMESG
  440.   {6, "log file name: %s", 0, 0, logfile, 65, NULL, NULL},
  441. #endif
  442.   {6, "xtrekrc file name: %s", 0, 0, xtrekrcfile, 65, NULL, NULL},
  443. #ifdef BEEPLITE
  444.   {3, "", &UseLite, 0, 0, 0, beeplite_options, &beeplite_range},
  445.   {2, "highlight/use default RCDs", &DefLite, 0, 0, 0, NULL, NULL},
  446.   {3, "No. of updates to highlight player: %d", &beep_lite_cycle_time_player,
  447.      0, 0, 0, NULL, &beeplite_player_range},
  448.   {3, "No. of updates to highlight planet: %d", &beep_lite_cycle_time_planet,
  449.      0, 0, 0, NULL, &beeplite_planet_range},
  450. #endif
  451.  
  452. #ifdef MAKE_XTREKRC
  453.   {17, "write configuration", &write_configuration, 0, 0, 0, NULL,
  454.   &write_configuration_range},
  455. #endif
  456.   {17, "done", ¬done, 0, 0, 0, NULL, NULL},
  457.   {-1, NULL, 0, 0, 0, 0, NULL, NULL}
  458. };
  459.  
  460. #define NUMOPTIONS(menu) ((sizeof((menu))/sizeof((menu)[0]))-1)
  461.  
  462. #if __STDC__ || defined(__cplusplus)
  463. #define P_(s) s
  464. #else
  465. #define P_(s) ()
  466. #endif
  467.  
  468. /* option.c */
  469. static optionrefresh P_ ((register struct option * op));
  470. static AddOptMenu P_ ((struct option NewMenu[], int updated));
  471. static int NumOptions P_ ((struct option OpMenu[]));
  472.  
  473. #undef P_
  474.  
  475.  
  476. /* option menu sizes and such */
  477. #define OPTIONBORDER    2
  478. #define OPTIONLEN    48
  479.  
  480. /* Set up the option menus and window. */
  481. optionwindow ()
  482. {
  483.   register int    i;
  484.   char           *home = (char *) getenv ("HOME");
  485.   char           *name = getdefault ("name");
  486.   /* Init not done flag */
  487.   notdone = 1;
  488.  
  489.   strcpy (cname, me->p_name);
  490.   *newkeys = '\0';
  491.   newckeys[0] = '\0';
  492.  
  493. #ifdef SHORT_PACKETS
  494.   *recv_threshold_s = 0;
  495. #endif
  496.  
  497. #ifdef FEATURE
  498.   if (macrokey == 27)
  499.     strcpy (macro_key, "ESC");
  500.   else if (macrokey == 9)
  501.     strcpy (macro_key, "TAB");
  502.   else
  503.   {
  504.     macro_key[0] = (char) macrokey;
  505.     macro_key[1] = '\0';
  506.   }
  507.   
  508.   make_singlemacrokeys (singlemacros);
  509. #endif
  510.  
  511. #ifdef PLIST
  512.   if (plist && strcmp (oplist, plist)) {
  513.     strcpy (oplist, plist);
  514.     strcpy (nplist, plist);
  515.   }
  516. #endif
  517.  
  518. #ifdef LOGMESG
  519.   if (logFileName)
  520.     strcpy (logfile, logFileName);
  521.   else
  522.     logfile[0] = '\0';
  523.  
  524.   if (defaultsFile)
  525.     strcpy (xtrekrcfile, defaultsFile);
  526.   else if (!home || !findDefaults (home, xtrekrcfile))
  527.     xtrekrcfile[0] = '\0';
  528. #endif
  529.  
  530.   if (FirstMenu == NULL)
  531.   {
  532.     MaxOptions = InitOptionMenus ();
  533.     if (MaxOptions < 0)
  534.     {
  535.       fprintf (stderr, "InitOptionMenus() error %d!\n", MaxOptions);
  536.       notdone = 0;
  537.       return;
  538.     }
  539.   }
  540.  
  541. #ifdef MAP_NAMES
  542.   old_draw_map_names = draw_map_names;
  543.   old_show_owner_map = show_owner_map;
  544. #endif
  545.  
  546.   /* Create window big enough to hold option windows */
  547.   if (optionWin == NULL)
  548.   {
  549.  
  550.     optionWin = W_MakeMenu ("option", WINSIDE + 10, -BORDER + 10, OPTIONLEN,
  551.                 MaxOptions, baseWin, OPTIONBORDER);
  552.  
  553. #ifdef TCURSORS
  554.     W_DefineArrowCursor (optionWin);
  555. #endif
  556.  
  557.     CurrentMenu = FirstMenu;
  558.  
  559.     RefreshOptions ();
  560.   }
  561.   W_ResizeMenu (optionWin, OPTIONLEN, CurrentMenu->numopt);
  562.   /* Map window */
  563.   W_MapWindow (optionWin);
  564. }
  565.  
  566. /* refresh all current options */
  567. RefreshOptions ()
  568. {
  569.   int             i;
  570.   struct option_menu *option;
  571.  
  572.   if (notdone == 0 || (option = CurrentMenu) == NULL)
  573.     return;
  574.  
  575.   for (i = 0; i < option->numopt; i++)
  576.   {
  577.     optionrefresh (&(option->menu[i]));
  578.   }
  579.  
  580. #ifdef nodef
  581.   if (option->numopt < MaxOptions)
  582.     for (i = option->numopt; i < MaxOptions; i++)
  583.     {
  584.       OptionClear (i);
  585.     }
  586. #endif
  587. }
  588.  
  589. #ifdef nodef
  590. /* blank out option line 'i' */
  591. OptionClear (i)
  592. {
  593.   char           *blanktext = "                                               ";
  594.   if (optionWin && notdone)
  595.     W_WriteText (optionWin, 0, i, textColor, blanktext, OPTIONLEN, 0);
  596. }
  597.  
  598. #endif
  599.  
  600. /* Redraw the specified option entry */
  601. optionredrawtarget (win)
  602.   W_Window        win;
  603. {
  604.   register struct option *op;
  605.  
  606. #ifdef nodef
  607.   if (notdone == 0)
  608.     return;
  609. #endif
  610.  
  611.   for (op = CurrentMenu->menu; op->op_text; op++)
  612.   {
  613.     if (op->op_targetwin && win == *op->op_targetwin)
  614.     {
  615.       optionrefresh (op);
  616.       break;
  617.     }
  618.   }
  619. }
  620.  
  621. /* Redraw the specified option option */
  622. optionredrawoption (ip)
  623.   int            *ip;
  624. {
  625.   register struct option *op;
  626.  
  627.   if (notdone == 0)
  628.     return;
  629.  
  630.   for (op = CurrentMenu->menu; op->op_num >= 0; op++)
  631.   {
  632.     if (ip == op->op_option)
  633.     {
  634.       optionrefresh (op);
  635.       break;
  636.     }
  637.   }
  638. }
  639.  
  640. /* Refresh the option window given by the option struct */
  641. static
  642.                 optionrefresh (op)
  643.   register struct option *op;
  644. {
  645.   register int    on;
  646.   char            buf[BUFSIZ];
  647.  
  648.   if (op == NULL || notdone == 0)
  649.     return;
  650.  
  651.   if (op->op_string)
  652.   {
  653.     (void) sprintf (buf, op->op_text, op->op_string);
  654.   }
  655.   else if (op->op_array)
  656.   {                /* Array of strings */
  657.     strcpy (buf, op->op_array[*op->op_option]);
  658.   }
  659.   else if (op->op_range)
  660.   {
  661.     (void) sprintf (buf, op->op_text, *(op->op_option));
  662.   }
  663.   else
  664.   {
  665.     /* Either a boolean or a window */
  666.     if (op->op_option)
  667.       on = *op->op_option;    /* use int for status */
  668.     else if (op->op_targetwin)
  669.       on = W_IsMapped (*op->op_targetwin);    /* use window for status */
  670.     else
  671.       on = 1;            /* shouldn't happen */
  672.  
  673.     if (!on)
  674.       strcpy (buf, "Don't ");
  675.     else
  676.       buf[0] = '\0';
  677.     strcat (buf, op->op_text);
  678.   }
  679.  
  680.   if (islower (buf[0]))
  681.     buf[0] = toupper (buf[0]);
  682.  
  683.   if (op->op_num == 0)
  684.   {                /* title */
  685.     W_WriteText (optionWin, 0, op->op_num, W_Yellow, buf, strlen (buf), 0);
  686.   }
  687.   else if (op->op_num == 1)
  688.   {                /* "click" entry */
  689.     W_WriteText (optionWin, 0, op->op_num, W_Green, buf, strlen (buf), 0);
  690.   }
  691.   else
  692.     W_WriteText (optionWin, 0, op->op_num, textColor, buf, strlen (buf), 0);
  693. }
  694.  
  695. /* deal with events sent to the option window */
  696. optionaction (data)
  697.   W_Event        *data;
  698. {
  699.   register struct option *op;
  700.   int             i;
  701.   register char  *cp;
  702.  
  703.   if (data->y >= CurrentMenu->numopt)
  704.   {
  705.     W_Beep ();
  706.     return (0);
  707.   }
  708.   if (notdone == 0)
  709.     return (0);
  710.  
  711.   op = &(CurrentMenu->menu[data->y]);
  712.  
  713. #ifdef MAKE_XTREKRC
  714.   if (op->op_option == &write_configuration)
  715.   {
  716.     showDefaults = 1;
  717.     warning ("Writing configuration file: $(HOME)/.cow-literc");
  718.     make_xtrekrc (1);
  719.     showDefaults = 0;
  720.   }
  721. #endif
  722.  
  723.   /* Update string; don't claim keystrokes for non-string options */
  724.   /* deal with options with string input first */
  725.   if (op->op_string == 0)
  726.   {
  727.     if (data->type == W_EV_KEY)
  728.       return (0);
  729.   }
  730.   else
  731.   {
  732.     if (data->type == W_EV_BUTTON)
  733.       return (0);
  734.     switch (data->key)
  735.     {
  736.  
  737.       case '\b':        /* delete character */
  738.       case '\177':
  739.     cp = op->op_string;
  740.     i = strlen (cp);
  741.     if (i > 0)
  742.     {
  743.       cp += i - 1;
  744.       *cp = '\0';
  745.     }
  746.     break;
  747.  
  748.       case '\027':        /* word erase */
  749.     cp = op->op_string;
  750.     i = strlen (cp);
  751.     /* back up over blanks */
  752.     while (--i >= 0 && isspace (cp[i]));
  753.     i++;
  754.     /* back up over non-blanks */
  755.     while (--i >= 0 && !isspace (cp[i]));
  756.     i++;
  757.     cp[i] = '\0';
  758.     break;
  759.  
  760.       case '\025':        /* kill line */
  761.       case '\030':
  762.     op->op_string[0] = '\0';
  763.     break;
  764.  
  765.       default:            /* add character to the list */
  766.     if (data->key < 32 || data->key > 127)
  767.       break;
  768.     cp = op->op_string;
  769.     i = strlen (cp);
  770.     if (i < (op->op_size - 1) && !iscntrl (data->key))
  771.     {
  772.       cp += i;
  773.       cp[1] = '\0';
  774.       cp[0] = data->key;
  775.     }
  776.     else
  777.       W_Beep ();
  778.     break;
  779.     }
  780.   }
  781.  
  782.   /* Toggle int, if it exists */
  783.   if (op->op_array)
  784.   {
  785.     if (op->op_range)
  786.     {
  787.       if (data->key == W_RBUTTON)
  788.       {
  789.     (*op->op_option) += op->op_range->increment;
  790.       }
  791.       else if (data->key == W_MBUTTON)
  792.       {
  793.     (*op->op_option) = op->op_range->min_value;
  794.       }
  795.       else if (data->key == W_LBUTTON)
  796.       {
  797.     (*op->op_option) -= op->op_range->increment;
  798.       }
  799.       /* wrap value around within option range */
  800.       if (*(op->op_option) > op->op_range->max_value)
  801.     *(op->op_option) = op->op_range->min_value;
  802.  
  803.       if (*(op->op_option) < op->op_range->min_value)
  804.     *(op->op_option) = op->op_range->max_value;
  805.     }
  806.     else if (data->key == W_RBUTTON)
  807.     {
  808.       (*op->op_option)++;
  809.       if (*(op->op_array)[*op->op_option] == '\0')
  810.       {
  811.     *op->op_option = 0;
  812.       }
  813.     }
  814.     else if (data->key == W_MBUTTON)
  815.     {
  816.       /* set option number to zero on the middle key to ease shutoff */
  817.       *op->op_option = 0;
  818.     }
  819.     else if (data->key == W_LBUTTON)
  820.     {
  821.       /* if left button, decrease option  */
  822.       (*op->op_option)--;
  823.       /* if decreased too far, set to top option */
  824.       if (*(op->op_option) < 0)
  825.       {
  826.     *op->op_option = 0;
  827.     while (*(op->op_array)[*op->op_option] != '\0')
  828.     {
  829.       (*op->op_option)++;
  830.     }
  831.     (*op->op_option)--;
  832.       }
  833.     }
  834.  
  835. #ifdef ROTATERACE
  836.     if (op->op_option == &rotate && rotate != old_rotate)
  837.     {
  838.       register        i;
  839.       register struct planet *l;
  840.       register struct player *j;
  841.  
  842.       redrawall = 1;
  843.       reinitPlanets = 1;
  844.  
  845.       for (i = 0, l = planets; i < MAXPLANETS; i++, l++)
  846.       {
  847.     if (rotate)
  848.     {
  849.       rotate_deg = -old_rotate_deg + rotate * 64;
  850.       rotate_coord (&l->pl_x, &l->pl_y, rotate_deg,
  851.             GWIDTH / 2, GWIDTH / 2);
  852.       rotate_deg = rotate * 64;
  853.     }
  854.     else
  855.     {
  856.       rotate_deg = -old_rotate_deg;
  857.       rotate_coord (&l->pl_x, &l->pl_y, rotate_deg,
  858.             GWIDTH / 2, GWIDTH / 2);
  859.       rotate_deg = 0;
  860.     }
  861.       }
  862.  
  863.       /*
  864.        * we could wait for the server to do this but looks better if we do it
  865.        * now.
  866.        */
  867.       for (i = 0, j = players; i < MAXPLAYER; i++, j++)
  868.       {
  869.     if (j->p_status != PALIVE)
  870.       continue;
  871.     if (rotate)
  872.     {
  873.       rotate_deg = -old_rotate_deg + rotate * 64;
  874.       rotate_coord (&j->p_x, &j->p_y, rotate_deg,
  875.             GWIDTH / 2, GWIDTH / 2);
  876.       rotate_dir (&j->p_dir, rotate_deg);
  877.  
  878.       rotate_deg = rotate * 64;
  879.     }
  880.     else
  881.     {
  882.       rotate_deg = -old_rotate_deg;
  883.       rotate_coord (&j->p_x, &j->p_y, rotate_deg,
  884.             GWIDTH / 2, GWIDTH / 2);
  885.       rotate_dir (&j->p_dir, rotate_deg);
  886.       rotate_deg = 0;
  887.     }
  888.       }
  889.       /* phasers/torps/etc .. wait for server */
  890.  
  891.       old_rotate = rotate;
  892.       old_rotate_deg = rotate_deg;
  893.     }
  894. #endif
  895.   }
  896.   else if (op->op_range)
  897.   {
  898.     if (data->key == W_RBUTTON)
  899.     {
  900.       (*op->op_option) += op->op_range->increment;
  901.     }
  902.     else if (data->key == W_MBUTTON)
  903.     {
  904.       (*op->op_option) = op->op_range->min_value;
  905.     }
  906.     else if (data->key == W_LBUTTON)
  907.     {
  908.       (*op->op_option) -= op->op_range->increment;
  909.     }
  910.     /* wrap value around within option range */
  911.     if (*(op->op_option) > op->op_range->max_value)
  912.       *(op->op_option) = op->op_range->min_value;
  913.     if (*(op->op_option) < op->op_range->min_value)
  914.       *(op->op_option) = op->op_range->max_value;
  915.   }
  916.   else if (op->op_option)
  917.   {
  918.     *op->op_option = !*op->op_option;
  919.  
  920. #ifdef NETSTAT
  921.     /* XXXXXX KLUDGE */
  922.     if (op->op_option == &netstat)
  923.     {
  924.       if (netstat && !W_IsMapped (lMeter))
  925.       {
  926.     ns_init (1);
  927.     W_MapWindow (lMeter);
  928.       }
  929.       else if (!netstat && W_IsMapped (lMeter))
  930.       {
  931.     W_UnmapWindow (lMeter);
  932.       }
  933.     }
  934. #endif
  935.  
  936. #ifdef PLIST
  937.     /* XXXXXX KLUDGE */
  938.     if (op->op_option == &newPlist)
  939.     {
  940.       W_ClearWindow (playerw);
  941.       playerlist ();
  942.     }
  943. #endif
  944.  
  945.     if (op->op_option == &sortPlayers)
  946.     {
  947.       W_ClearWindow (playerw);
  948.       playerlist ();
  949.     }
  950.  
  951. #ifdef DASHBOARD
  952.     if (op->op_option == &dashboard)
  953.     {
  954.       W_ClearWindow (tstatw);
  955.       redrawTstats ();
  956.     }
  957. #endif
  958.  
  959. #ifdef NEW_DASHBOARD_2
  960.     if (op->op_option == &cup_half_full)
  961.     {
  962.       W_ClearWindow (tstatw);
  963.       redrawTstats ();
  964.     }
  965. #endif
  966.   }
  967.   /* Map/unmap window, if it exists */
  968.   if (op->op_targetwin)
  969.   {
  970.     if (W_IsMapped (*op->op_targetwin))
  971.       W_UnmapWindow (*op->op_targetwin);
  972.     else
  973.     {
  974.  
  975. #ifdef XTREKRC_HELP
  976.       if (op->op_targetwin == &defWin)
  977.     showdef ();
  978.       else
  979. #endif
  980.  
  981.       {
  982.     W_MapWindow (*op->op_targetwin);
  983.     if (*op->op_targetwin == udpWin)
  984.       udpwindow ();
  985.  
  986. #ifdef PING
  987.     if (*op->op_targetwin == pStats)
  988.       redrawPStats ();
  989. #endif
  990.       }
  991.     }
  992.   }
  993.   /* deal with possible menu change */
  994.   if (MenuPage != CurrentMenu->page_num)
  995.   {
  996.     SetMenuPage (MenuPage);
  997.     RefreshOptions ();
  998.   }
  999.   if (!notdone)            /* if done, that is */
  1000.     optiondone ();
  1001.   else
  1002.     optionrefresh (op);
  1003.  
  1004.  
  1005.   return (1);
  1006. }
  1007.  
  1008. /*
  1009.  * find the menu in the menus linked list that matches the one in the *
  1010.  * argument
  1011.  */
  1012. SetMenuPage (pagenum)
  1013.   int             pagenum;
  1014. {
  1015.   int             i = 1;
  1016.   if (FirstMenu != NULL)
  1017.     for (CurrentMenu = FirstMenu; CurrentMenu->Next != NULL &&
  1018.     CurrentMenu->page_num != pagenum; i++, CurrentMenu = CurrentMenu->Next);
  1019.   W_ResizeMenu (optionWin, OPTIONLEN, CurrentMenu->numopt);
  1020. }
  1021.  
  1022. optiondone ()
  1023. {
  1024.   char           *str;
  1025.  
  1026.   /* Unmap window */
  1027.   W_UnmapWindow (optionWin);
  1028.  
  1029.   /* update keymap */
  1030.   for (str = newkeys; *str != '\0'; str += 2)
  1031.   {
  1032.     if ((*str >= 32 && *str < 127) || *str == 'O')
  1033.     {
  1034.       if (*(str + 1) == '\0')
  1035.     break;
  1036.       mystats->st_keymap[*str - 32] = *(str + 1);
  1037.     }
  1038.     if (*(str + 1) == '\0')
  1039.       break;
  1040.   }
  1041.   *newkeys = '\0';
  1042.  
  1043. #ifdef CONTROL_KEY
  1044.   /* update ckeymap */
  1045.   if (newckeys[0] == '^')
  1046.     for (str = newckeys; *str != '\0';)
  1047.     {
  1048.       if (*str == '^')
  1049.     str++;
  1050.       else
  1051.     break;
  1052.  
  1053.       if (*str >= 32 && *str < 127)
  1054.       {
  1055.     if (*(str + 1) == '\0')
  1056.       break;
  1057.  
  1058.     if (*(str + 1) == '^')
  1059.     {
  1060.       if (*(str + 2) == '\0')
  1061.         break;
  1062.  
  1063.       mystats->st_keymap[*str - 32 + 96] = (char) (*(str + 2) + 96);
  1064.       str += 3;
  1065.     }
  1066.     else
  1067.     {
  1068.       mystats->st_keymap[*str - 32 + 96] = *(str + 1);
  1069.       str += 2;
  1070.     }
  1071.       }
  1072.       else
  1073.     break;
  1074.     }
  1075.  
  1076.   newckeys[0] = '\0';
  1077. #endif
  1078.  
  1079. #ifdef FEATURE
  1080.   if (DefLite)
  1081.     litedefaults ();
  1082. #endif
  1083.   
  1084.   /* update buttonmap */
  1085.   if ((str = newbuttons) != NULL)
  1086.   {
  1087.     while (*str != '\0')
  1088.     {
  1089.       switch (*str++)
  1090.       {
  1091.     case '1':
  1092.       buttonmap[1] = *str;
  1093.       break;
  1094.     case '2':
  1095.       buttonmap[2] = *str;
  1096.       break;
  1097.     case '3':
  1098.       buttonmap[3] = *str;
  1099.       break;
  1100.  
  1101. #ifdef SHIFTED_MOUSE
  1102.     case '4':
  1103.       buttonmap[4] = *str;
  1104.       break;
  1105.     case '5':
  1106.       buttonmap[5] = *str;
  1107.       break;
  1108.     case '6':
  1109.       buttonmap[6] = *str;
  1110.       break;
  1111.     case '7':
  1112.       buttonmap[7] = *str;
  1113.       break;
  1114.     case '8':
  1115.       buttonmap[8] = *str;
  1116.       break;
  1117.     case '9':
  1118.       buttonmap[9] = *str;
  1119.       break;
  1120.     case 'a':
  1121.       buttonmap[10] = *str;
  1122.       break;
  1123.     case 'b':
  1124.       buttonmap[11] = *str;
  1125.       break;
  1126.     case 'c':
  1127.       buttonmap[12] = *str;
  1128.       break;
  1129. #endif
  1130.  
  1131.     default:
  1132.       fprintf (stderr, "%c ignored in buttonmap\n", *(str - 1));
  1133.       break;
  1134.       }
  1135.       str++;
  1136.     }
  1137.   }
  1138.   newbuttons[0] = '\0';
  1139.  
  1140. #ifdef PLIST
  1141.   if (plist && strcmp (oplist, nplist) && newPlist)
  1142.   {
  1143.     strcpy (plist, oplist);
  1144.     no_init_plist = 1;
  1145.     playerlistnum ();
  1146.     playerlist ();
  1147.     no_init_plist = 0;
  1148.   }
  1149. #endif
  1150.  
  1151. #ifdef FEATURE
  1152.   if (!strcmp (macro_key, "ESC"))
  1153.     macrokey = 27;
  1154.   else if (!strcmp (macro_key, "TAB"))
  1155.     macrokey = 9;
  1156.   else if (macro_key[0] != '\0')
  1157.     macrokey = macro_key[0];
  1158.  
  1159.   if (singlemacros [0])
  1160.   {    
  1161.     int i;
  1162.     char *str = singlemacros, buf [33];
  1163.     
  1164.     for (i = 0; *str; str++)
  1165.       if (*str == '^')
  1166.         buf [i++] = (char) (*(++str) + 96);
  1167.       else
  1168.         buf [i++] = *str;
  1169.         
  1170.     buf [i] = '\0';
  1171.  
  1172.     if (singleMacro)
  1173.       strcpy (singleMacro, buf);
  1174.     else
  1175.       singleMacro = (char *) strdup (buf);
  1176.   }
  1177. #endif
  1178.  
  1179. #ifdef LOGMESG
  1180.   if (logFileName && strcmp (logFileName, logfile))
  1181.     logFileName = logfile;
  1182.   else if (logFileName == NULL && logfile[0] != '\0')
  1183.     logFileName = logfile;
  1184. #endif
  1185.  
  1186. #ifdef LOGMESG
  1187.   if (defaultsFile && strcmp (defaultsFile, xtrekrcfile))
  1188.     defaultsFile = xtrekrcfile;
  1189.   else if (defaultsFile == NULL && xtrekrcfile[0] != '\0')
  1190.     defaultsFile = xtrekrcfile;
  1191. #endif
  1192.  
  1193. #ifdef SHORT_PACKETS
  1194.   {
  1195.     int             nt = atoi (recv_threshold_s);
  1196.     if (recv_threshold != nt)
  1197.     {
  1198.       recv_threshold = nt;
  1199.       sendThreshold (recv_threshold);
  1200.     }
  1201.     *recv_threshold_s = 0;
  1202.   }
  1203. #endif
  1204.  
  1205.   /* optionrefresh(&(option[KEYMAP])); Not sure why this is really needed */
  1206.  
  1207.   sendOptionsPacket ();        /* update server as to the client's options */
  1208.  
  1209.   if (updateSpeed != lastUpdateSpeed)
  1210.   {
  1211.     sendUpdatePacket (1000000 / updateSpeed);
  1212.     lastUpdateSpeed = updateSpeed;
  1213.  
  1214. #ifdef NETSTAT
  1215.     updatespeed = updateSpeed;
  1216. #endif                /* NETSTAT */
  1217.   }
  1218.  
  1219. #ifdef BUTTON_KEYMAP_WINDOW
  1220.   if (W_IsMapped (but_key_win))
  1221.     {
  1222.       W_ClearWindow (but_key_win);
  1223.       showkeymaps ();
  1224.     }
  1225. #endif
  1226.  
  1227. #ifdef SHORT_PACKETS
  1228.   if (recv_short != recv_short_opt)
  1229.   {
  1230.     /* we don't set recv_short .. that's done in socket.c */
  1231.     if (recv_short_opt)
  1232.       sendShortReq (SPK_VON);
  1233.     else
  1234.       sendShortReq (SPK_VOFF);
  1235.   }
  1236. #endif
  1237.  
  1238. #ifdef MAP_NAMES
  1239.   if (old_draw_map_names != draw_map_names)
  1240.     redrawall = 2;
  1241.     
  1242.   if (old_show_owner_map != show_owner_map)
  1243.     redrawall = 2;
  1244. #endif
  1245.  
  1246.   if (old_showgalactic != showgalactic)
  1247.   {
  1248.     old_showgalactic = showgalactic;
  1249.     if (!redrawall)
  1250.       redrawall = 2;
  1251.   }
  1252. }
  1253.  
  1254. /* set up menus linked list */
  1255. int
  1256.                 InitOptionMenus ()
  1257. {
  1258.   int             i = 1;
  1259.   int             maxopts = 0;
  1260.  
  1261. #ifdef PLIST
  1262.   if (getdefault ("playerlist") == NULL)
  1263.   {
  1264.     if (newPlist)
  1265.       strcpy (oplist, "nTR N  K lrSd");
  1266.     else {
  1267.       strcpy (oplist, "nTRNKWLr O D d ");
  1268.   }
  1269.     strcpy(nplist,oplist);
  1270.   }
  1271.   else {
  1272.     strcpy (oplist, getdefault ("playerlist"));
  1273.     strcpy (nplist, oplist);
  1274.   }
  1275. #endif
  1276.  
  1277.   IFDEBUG (printf ("Adding OptionMenus\n");
  1278.   )
  1279.   /* AddOptMenu( &OptionsMenu, 0); */
  1280.     AddOptMenu (Features_Menu, 0);
  1281.   AddOptMenu (Window_Menu, 0);
  1282.   AddOptMenu (SillyFeatures_Menu, 0);
  1283.   AddOptMenu (SillyFeatures_Menu1, 0);
  1284.   AddOptMenu (SillyFeatures_Menu2, 0);
  1285.  
  1286.   for (i = 0, CurrentMenu = FirstMenu; CurrentMenu != NULL;
  1287.        i++, CurrentMenu = CurrentMenu->Next)
  1288.   {
  1289.     CurrentMenu->page_num = i;    /* repage the menus.. */
  1290.     if (CurrentMenu->numopt > maxopts)
  1291.       maxopts = CurrentMenu->numopt;
  1292.   }
  1293.   CurrentMenu = FirstMenu;
  1294.   Menus_Range.max_value = i - 1;
  1295.   IFDEBUG (printf ("OptionMenus Added! Maxopt = %d \n", i);
  1296.   )
  1297.     return maxopts;
  1298. }
  1299.  
  1300. static
  1301.                 AddOptMenu (NewMenu, updated)
  1302.   struct option   NewMenu[];
  1303.   int             updated;
  1304. {
  1305.   struct option_menu *menuptr;
  1306.   struct option_menu *newmenu;
  1307.   int             i = 0;
  1308.  
  1309.   IFDEBUG (printf ("AddOptMenu\n");
  1310.   )
  1311.     menuptr = FirstMenu;
  1312.  
  1313.   newmenu = (struct option_menu *) malloc (sizeof (struct option_menu));
  1314.   if (newmenu == NULL)
  1315.   {
  1316.     perror ("Malloc Error adding a menu");
  1317.     return;
  1318.   }
  1319.   /* add to list */
  1320.   if (FirstMenu == NULL)
  1321.   {
  1322.     FirstMenu = newmenu;
  1323.   }
  1324.   else
  1325.   {
  1326.     for (i = 0, menuptr = FirstMenu; menuptr->Next != NULL; menuptr = menuptr->Next)
  1327.       i++;
  1328.     menuptr->Next = newmenu;
  1329.   }
  1330.   newmenu->page_num = i;
  1331.   newmenu->Next = NULL;
  1332.   newmenu->numopt = NumOptions (NewMenu);
  1333.   newmenu->menu = NewMenu;
  1334.   newmenu->updated = updated;
  1335.   IFDEBUG (printf ("Menu Added! \n", i);
  1336.   )
  1337. }
  1338.  
  1339. static int
  1340.                 NumOptions (OpMenu)
  1341.   struct option   OpMenu[];
  1342. {
  1343.   int             i = 0;
  1344.   struct option  *ptr;
  1345.  
  1346.   ptr = &OpMenu[0];
  1347.   for (i = 0; ptr->op_num != -1 && ptr->op_option != ¬done; i++)
  1348.   {
  1349.     IFDEBUG (printf ("Option #%d..\n", i);
  1350.     )
  1351.       IFDEBUG (if (ptr->op_text != NULL) printf ("OP_Text:%s\n", ptr->op_text);
  1352.     )
  1353.       ptr = &OpMenu[i];
  1354.     ptr->op_num = i;
  1355.   }
  1356.  
  1357.   IFDEBUG (printf ("NumOptions in this menu: %d\n", i);
  1358.   )
  1359.     return i;
  1360. }
  1361.  
  1362. /*
  1363.  * a function that could be called regularly, to deal with menus that * might
  1364.  * be updated by external events. I.e. the udp menu!
  1365.  */
  1366. UpdateOptions ()
  1367. {
  1368.   if (notdone == 0)
  1369.     return;            /* don't update if menu isn't in use */
  1370.   if (CurrentMenu->updated)
  1371.     RefreshOptions ();
  1372. }
  1373.